/**
 * SA扫描管理通用工具函数
 */
import React from 'react';
import dayjs from 'dayjs';
import { message } from 'antd';
import * as XLSX from 'xlsx';

/**
 * 格式化日期时间
 * @param dateTime 日期时间字符串
 * @param format 格式化模板，默认 'YYYY-MM-DD HH:mm:ss'
 * @returns 格式化后的字符串，如果输入为空则返回 '-'
 */
export const formatDateTime = (dateTime: string, format: string = 'YYYY-MM-DD HH:mm:ss'): string => {
    if (!dateTime) return '-';
    return dayjs(dateTime).format(format);
};

/**
 * 格式化耗时（毫秒转秒）
 * @param ms 毫秒数
 * @param decimals 小数位数，默认2位
 * @returns 格式化后的字符串，如 "1.23s"
 */
export const formatDuration = (ms: number, decimals: number = 2): string => {
    if (!ms && ms !== 0) return '-';
    return `${(ms / 1000).toFixed(decimals)}s`;
};

/**
 * 格式化文件大小
 * @param bytes 字节数
 * @returns 格式化后的字符串，如 "1.23 MB"
 */
export const formatFileSize = (bytes: number): string => {
    if (!bytes && bytes !== 0) return '-';

    const units = ['B', 'KB', 'MB', 'GB', 'TB'];
    let size = bytes;
    let unitIndex = 0;

    while (size >= 1024 && unitIndex < units.length - 1) {
        size /= 1024;
        unitIndex++;
    }

    return `${size.toFixed(2)} ${units[unitIndex]}`;
};

/**
 * 格式化数字，添加千分位分隔符
 * @param num 数字
 * @returns 格式化后的字符串，如 "1,234,567"
 */
export const formatNumber = (num: number): string => {
    if (!num && num !== 0) return '-';
    return num.toLocaleString('zh-CN');
};

/**
 * 截断长文本
 * @param text 文本
 * @param maxLength 最大长度
 * @returns 截断后的文本
 */
export const truncateText = (text: string, maxLength: number = 50): string => {
    if (!text) return '-';
    if (text.length <= maxLength) return text;
    return `${text.substring(0, maxLength)}...`;
};

/**
 * 显示成功消息
 * @param content 消息内容
 */
export const showSuccess = (content: string): void => {
    message.success({
        content,
        duration: 3,
        style: {
            marginTop: '20vh'
        }
    });
};

/**
 * 显示错误消息
 * @param content 消息内容
 * @param error 错误对象（可选）
 */
export const showError = (content: string, error?: any): void => {
    const errorMsg = error?.message || error?.toString() || '';
    const fullMessage = errorMsg ? `${content}: ${errorMsg}` : content;

    message.error({
        content: fullMessage,
        duration: 5,
        style: {
            marginTop: '20vh'
        }
    });
};

/**
 * 显示警告消息
 * @param content 消息内容
 */
export const showWarning = (content: string): void => {
    message.warning({
        content,
        duration: 4,
        style: {
            marginTop: '20vh'
        }
    });
};

/**
 * 显示信息消息
 * @param content 消息内容
 */
export const showInfo = (content: string): void => {
    message.info({
        content,
        duration: 3,
        style: {
            marginTop: '20vh'
        }
    });
};

/**
 * 显示加载消息
 * @param content 消息内容
 * @returns 关闭函数
 */
export const showLoading = (content: string = '加载中...'): (() => void) => {
    const hide = message.loading({
        content,
        duration: 0,
        style: {
            marginTop: '20vh'
        }
    });
    return hide;
};

/**
 * 防抖函数
 * @param func 要防抖的函数
 * @param wait 等待时间（毫秒）
 * @returns 防抖后的函数
 */
export const debounce = <T extends (...args: any[]) => any>(
    func: T,
    wait: number = 300
): ((...args: Parameters<T>) => void) => {
    let timeout: NodeJS.Timeout | null = null;

    return function (this: any, ...args: Parameters<T>) {
        const context = this;

        if (timeout) {
            clearTimeout(timeout);
        }

        timeout = setTimeout(() => {
            func.apply(context, args);
        }, wait);
    };
};

/**
 * 节流函数
 * @param func 要节流的函数
 * @param wait 等待时间（毫秒）
 * @returns 节流后的函数
 */
export const throttle = <T extends (...args: any[]) => any>(
    func: T,
    wait: number = 300
): ((...args: Parameters<T>) => void) => {
    let timeout: NodeJS.Timeout | null = null;
    let previous = 0;

    return function (this: any, ...args: Parameters<T>) {
        const context = this;
        const now = Date.now();
        const remaining = wait - (now - previous);

        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            func.apply(context, args);
        } else if (!timeout) {
            timeout = setTimeout(() => {
                previous = Date.now();
                timeout = null;
                func.apply(context, args);
            }, remaining);
        }
    };
};

/**
 * 安全的JSON解析
 * @param jsonString JSON字符串
 * @param defaultValue 默认值
 * @returns 解析后的对象或默认值
 */
export const safeJsonParse = <T = any>(jsonString: string, defaultValue: T): T => {
    try {
        return JSON.parse(jsonString);
    } catch (error) {
        console.error('JSON解析失败:', error);
        return defaultValue;
    }
};

/**
 * 复制文本到剪贴板
 * @param text 要复制的文本
 * @returns Promise<boolean> 是否成功
 */
export const copyToClipboard = async (text: string): Promise<boolean> => {
    try {
        if (navigator.clipboard && window.isSecureContext) {
            await navigator.clipboard.writeText(text);
            showSuccess('复制成功');
            return true;
        } else {
            // 降级方案
            const textArea = document.createElement('textarea');
            textArea.value = text;
            textArea.style.position = 'fixed';
            textArea.style.left = '-999999px';
            textArea.style.top = '-999999px';
            document.body.appendChild(textArea);
            textArea.focus();
            textArea.select();

            const successful = document.execCommand('copy');
            textArea.remove();

            if (successful) {
                showSuccess('复制成功');
                return true;
            } else {
                showError('复制失败');
                return false;
            }
        }
    } catch (error) {
        showError('复制失败', error);
        return false;
    }
};

/**
 * 下载文件
 * @param blob Blob对象
 * @param filename 文件名
 */
export const downloadFile = (blob: Blob, filename: string): void => {
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
};

/**
 * 生成导出文件名
 * @param prefix 前缀
 * @param extension 扩展名，默认 'xlsx'
 * @returns 文件名，格式: prefix_YYYYMMDDHHmmss.extension
 */
export const generateExportFilename = (prefix: string, extension: string = 'xlsx'): string => {
    const timestamp = dayjs().format('YYYYMMDDHHmmss');
    return `${prefix}_${timestamp}.${extension}`;
};

/**
 * 验证是否为有效的单元ID
 * @param unitId 单元ID
 * @returns 是否有效
 */
export const isValidUnitId = (unitId: string): boolean => {
    if (!unitId || typeof unitId !== 'string') return false;
    // 单元ID通常是字母、数字、下划线、中划线的组合
    return /^[a-zA-Z0-9_-]+$/.test(unitId.trim());
};

/**
 * 导出数据到Excel
 * @param data 数据数组
 * @param columns 列配置数组，格式: [{ header: '列名', key: '字段名', formatter?: (value) => string }]
 * @param filename 文件名（不含扩展名）
 */
export const exportToExcel = (
    data: any[],
    columns: Array<{ header: string; key: string; formatter?: (value: any) => string }>,
    filename: string
): void => {
    try {
        if (!data || data.length === 0) {
            showWarning('没有数据可导出');
            return;
        }

        // 构建表头
        const headers = columns.map(col => col.header);

        // 构建数据行
        const rows = data.map(item => {
            return columns.map(col => {
                const value = item[col.key];
                // 如果有格式化函数，使用格式化函数
                if (col.formatter) {
                    return col.formatter(value);
                }
                // 处理空值
                if (value === null || value === undefined) {
                    return '-';
                }
                // 处理布尔值
                if (typeof value === 'boolean') {
                    return value ? '是' : '否';
                }
                return value;
            });
        });

        // 合并表头和数据
        const worksheetData = [headers, ...rows];

        // 创建工作表
        const worksheet = XLSX.utils.aoa_to_sheet(worksheetData);

        // 设置列宽（自动计算）
        const colWidths = columns.map((col, index) => {
            const headerLength = col.header.length;
            const maxDataLength = Math.max(
                ...rows.map(row => {
                    const cellValue = String(row[index] || '');
                    // 中文字符按2个字符计算
                    return cellValue.replace(/[\u4e00-\u9fa5]/g, 'aa').length;
                })
            );
            return { wch: Math.max(headerLength * 2, maxDataLength, 10) };
        });
        worksheet['!cols'] = colWidths;

        // 创建工作簿
        const workbook = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');

        // 生成Excel文件
        const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
        const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });

        // 下载文件
        const fullFilename = generateExportFilename(filename, 'xlsx');
        downloadFile(blob, fullFilename);

        showSuccess('导出成功');
    } catch (error) {
        console.error('导出Excel失败:', error);
        showError('导出失败', error);
    }
};
